package cn.com.dhcc.turbo.web.controller.registry;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.com.dhcc.app.core.base.BaseController;
import cn.com.dhcc.app.core.exception.NiceException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.handler.modulehandler.WhereCondition;
import cn.com.dhcc.app.core.handler.modulehandler.valuebean.LikeValue;
import cn.com.dhcc.app.core.handler.pagerhandler.Pager;
import cn.com.dhcc.app.core.handler.pagerhandler.PagerData;
import cn.com.dhcc.app.core.service.Log;
import cn.com.dhcc.app.core.service.Log.LOGTYPE;
import cn.com.dhcc.app.core.util.UUIDGenerator;
import cn.com.dhcc.app.pub.core.annotation.TurboMenu;
import cn.com.dhcc.app.pub.core.annotation.TurboMenu.LEAF_MENU;
import cn.com.dhcc.app.pub.core.consts.NodeInfoParam;
import cn.com.dhcc.app.pub.core.tag.AppTagEl;
import cn.com.dhcc.app.pub.core.util.HttpUtil;
import cn.com.dhcc.turbo.entity.exch.GapOwnerConf;
import cn.com.dhcc.turbo.entity.exch.GapUserConf;
import cn.com.dhcc.turbo.entity.registry.NodeInfo;
import cn.com.dhcc.turbo.entity.registry.OrgInfo;
import cn.com.dhcc.turbo.service.exch.DistributedNodeInfoService;
import cn.com.dhcc.turbo.service.exch.cmdata.GapOwnerConfService;
import cn.com.dhcc.turbo.service.registry.GapUserConfService;
import cn.com.dhcc.turbo.service.registry.LocalConfCallBack;
import cn.com.dhcc.turbo.service.registry.NodeInfoService;
import cn.com.dhcc.turbo.service.registry.OrgInfoService;
import cn.com.dhcc.turbo.service.registry.SzyFeatureMgr;
import cn.com.dhcc.turbo.service.registry.vo.RegistResult;

@Controller
@RequestMapping("/registry")
@TurboMenu(belongToMenu = LEAF_MENU.NODE_MGR)
public class NodeInfoController extends BaseController {
	@SuppressWarnings("deprecation")
	private static Logger logger = Log.getExistLogger(LOGTYPE.SAI);
	private static String regionCode = NodeInfoParam.NODE_REGION_CODE;
	@Autowired
	private OrgInfoService orgInfoService;
	@Autowired
	private NodeInfoService nodeService;
	
	@Autowired
	private SzyFeatureMgr registryPermissionMgr;
	@Autowired
	private LocalConfCallBack LocalConfCallBack;
	
	@Autowired
	private GapUserConfService gapUserConfService;
	
	@Autowired
	private GapOwnerConfService gapOwnerConfService;
	@Autowired
	private DistributedNodeInfoService distributedNodeInfoService;
	
	public static String LOCAL_NODE_SESSION_KEY = "_local_node_session";
	/**
	 * 获取节点信息列表
	 * 
	 * @param model
	 * @param pager
	 * @return
	 */
	@RequestMapping(value = "/node_info_list", method = RequestMethod.GET)
	public String list(Model model, Pager pager, String searchCode,
			String searchName) {
		WhereCondition condition = new WhereCondition();
		condition.where().eq("status", "1");
		condition.and().eq("islocal", "0");
		if (!"".equals(searchCode) && searchCode != null) {
			condition.and().like("node_code", LikeValue.roundLike(searchCode));
		}
		if (!"".equals(searchName) && searchName != null) {
			condition.and().like("node_name", LikeValue.roundLike(searchName));
		}
		condition.orderBy("mtime asc");
		try {
			PagerData<NodeInfo> pagerData = nodeService.list(pager, condition);
			model.addAttribute(DATA_KEY, pagerData.getDatas());
			setTotoal(model, pagerData.getTotal());
		} catch (Exception e) {
			logger.error("获取节点信息失败", e);
			return toAlertPage(model, e.getMessage());
		}
		return "registry/node_info_list";
	}

	@RequestMapping(value = "/node_info_add", method = RequestMethod.GET)
	public String nodeAdd(Model model, String nodeNetType,String pid) {
		try {
			List<OrgInfo> orgList = orgInfoService.getListByNetType(nodeNetType);
			List<OrgInfo> list = new ArrayList<OrgInfo>();
			String isNode = "0";//当前所选节点类型　0:虚拟节点　1：真实节点
			model.addAttribute("orgList", orgList);
			if(nodeNetType.equals(NodeInfoParam.NODE_NET_TYPE)){
				isNode="1";
			}else{
				if(NodeInfoParam.isManaagerNode() && NodeInfoParam.isMwr()){
					if(!nodeNetType.equals(NodeInfoParam.NODE_NET_TYPE)){
//						model.addAttribute("pid", pid);
						List<NodeInfo> nodelist = nodeService.getListByNetType("1".equals(NodeInfoParam.NODE_NET_TYPE)? "2" : "1");
						if(nodelist.size()==0){
							list.add(orgInfoService.get(NodeInfoParam.MWR_NODEREGION_CODE));
							model.addAttribute("orgList", list);
						}
					}
				}
			}
			model.addAttribute("netType", nodeNetType);
			model.addAttribute("isNode", isNode);
		} catch (Exception e) {
			logger.error("获取注册节点信息失败", e);
			return toAlertPage(model, e.getMessage());
		}
		return "registry/node_info_add";
	}

	/**
	 * 注册节点
	 * 
	 * @param model
	 * @param vo
	 * @param orgCode
	 * @param name
	 * @return
	 */
	@RequestMapping(value = "/add_node_info", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> addNode(Model model, NodeInfo vo, String orgCode, String newNodeName,String pid) {
		try {
			//获取到页面传入的访问地址参数，判断数据库中是否存在相同的url
			String registryUrl = vo.getInstallUrl();
			boolean isSameUrl = nodeService.isSameUrl(registryUrl);
			if (isSameUrl){
				//如果存在相同的url，则提示“注册节点失败，节点访问地址已被注册。”
				return jsonFailResult("注册节点信息失败，节点访问地址已被注册。");
			}
			NodeInfo localNode = nodeService.getLocalNode();
			
			vo.setId(UUIDGenerator.getUUID());
			vo.setNodeName(newNodeName);
			vo.setStatus("1");
			vo.setIsLocal("0");
			vo.setMtime(new Date());
			//同网络节点，节点编码自动生成，虚拟节点编码手动输入
			if(vo.getNetType().equals(NodeInfoParam.NODE_NET_TYPE)){
				int maxCode=nodeService.getMaxNodeCode(orgCode+ vo.getNetType());
				DecimalFormat df = new DecimalFormat("00");  
				String newNodeCode = orgCode+ vo.getNetType()+df.format(maxCode); 
				vo.setNodeCode(newNodeCode);
				vo.setPid(localNode.getId());
				if(vo.getNodeCode().substring(0,6).equals(localNode.getNodeCode().substring(0,6))){
					vo.setIsMgrNode("0");
				}else{
					vo.setIsMgrNode("1");
				}
				
			}else{
				NodeInfo localDummyNode = nodeService.getLocalDummyNode("1".equals(NodeInfoParam.NODE_NET_TYPE)? "2" : "1");
				if(NodeInfoParam.isManaagerNode() && NodeInfoParam.isMwr()){
					if(localDummyNode != null){
						vo.setPid(localDummyNode.getId());
						//如果水利虚拟节点已注册，则第二水利部节点为非管理节点
						if(vo.getNodeCode().substring(0,6).equals(localDummyNode.getNodeCode().substring(0,6))){
							vo.setIsMgrNode("0");
						}else{
							vo.setIsMgrNode("1");
						}
					}else{
						vo.setPid(NodeInfoParam.MWR_NODE_PID);
						vo.setIsMgrNode("1");
					}
				}else{
					if(localDummyNode != null){
						vo.setPid(localDummyNode.getId());
						//如果本地虚拟节点已注册，则第二本地虚拟节点为非管理节点
						vo.setIsMgrNode("0");
					}
				}
			}
			nodeService.insertAndSync(vo);
			return jsonSuccessResult("注册成功");
		} catch (ServiceException e) {
			return jsonFailResult("注册节点信息失败");
		} catch (NiceException e) {
			return jsonFailResult(e.getMessage());
		}
	}

	@RequestMapping(value = "/node_info_get", method = RequestMethod.GET)
	public String get(String id, Model model) {
		try {
			NodeInfo vo = nodeService.get(id);
			String isNode = "0";
			if(vo.getNetType().equals(NodeInfoParam.NODE_NET_TYPE)){
				isNode="1";
			}
			model.addAttribute("isNode", isNode);
			if(NodeInfoParam.isManaagerNode() && NodeInfoParam.isMwr()){
				model.addAttribute("ismgr","1");
			}
			model.addAttribute(DATA_KEY, vo);
			model.addAttribute("orgInfo",orgInfoService.get(vo.getNodeCode().substring(0, 6)));
		} catch (Exception e) {
			logger.error("获取节点信息失败", e);
			return toAlertPage(model, e.getMessage());
		}
		return "registry/node_info_get";
	}

	@RequestMapping(value = "/node_info_update", method = RequestMethod.GET)
	public String nodeUpdate(String id, Model model) {
		try {

			NodeInfo vo = nodeService.get(id);
			String isNode = "0";
			if(vo.getNetType().equals(NodeInfoParam.NODE_NET_TYPE)){
				isNode="1";
			}
			model.addAttribute("isNode", isNode);
			OrgInfo orgInfo = orgInfoService.get(vo.getNodeCode().substring(0,
					6));
			model.addAttribute(DATA_KEY, vo);
			model.addAttribute("orgInfo", orgInfo);
		} catch (Exception e) {
			logger.error("注册节点信息失败", e);
			return toAlertPage(model, e.getMessage());
		}
		return "registry/node_info_update";
	}

	/**
	 * 修改节点信息
	 * 
	 * @param model
	 * @param vo
	 * @param orgCode
	 * @param name
	 * @return
	 */
	@RequestMapping(value = "/update_node_info", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> updateNode(Model model, HttpSession httpSession,NodeInfo vo,
			String newNodeName) {
		try {
			vo.setNodeName(newNodeName);
			vo.setMtime(new Date());
			NodeInfo localNode=nodeService.getLocalNode();
			if (vo.getNodeCode().equals(localNode.getNodeCode())) {//如果是本节点更新,是否有网闸从配置文件中取
				vo.setHasGap(NodeInfoParam.hasGap);
			}
			String nodeCode = distributedNodeInfoService.getNodeCode(vo.getInstallUrl());
			if("".equals(nodeCode) || !vo.getNodeCode().equals(nodeCode)){
				return jsonFailResult(" 修改节点信息失败,节点访问地址已被注册");
			}
			nodeService.updateAndSync(vo);
			if("1".equals(vo.getIsLocal())){
				httpSession.removeAttribute(LOCAL_NODE_SESSION_KEY);
				httpSession.setAttribute(LOCAL_NODE_SESSION_KEY, vo);
			}
			return jsonSuccessResult("修改节点信息成功");
		} catch (Exception e) {
			logger.error(" 修改节点信息失败", e);
			return jsonFailResult(" 修改节点信息失败");
		}
	}

	@RequestMapping(value = "/node_info_delete", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> delete(Model model, String id) {
		String msg = "";
		try {
			/*if (sysInfoService.getSysInfoByNodeId(id).size() > 0) {
				return jsonFailResult("删除失败,节点内已注册了业务系统，无法删除！");
			}*/
			NodeInfo vo = nodeService.get(id);
			vo.setStatus("0");
			nodeService.updateAndSync(vo);
			msg = "删除成功";
			return jsonSuccessResult(msg);
		} catch (Exception e) {
			msg = "删除失败";
			logger.error(msg, e);
			return jsonFailResult(msg);
		}
	}

	@RequestMapping(value = "/batch_node_info_delete", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> batchDelete(@RequestParam("ids") String[] ids) {
		String msg = "";
		try {
			nodeService.batchDelete(ids);
			msg = "批量删除成功";
			return jsonSuccessResult(msg);
		} catch (Exception e) {
			msg = "批量删除失败";
			logger.error(msg, e);
			return jsonFailResult(msg);
		}
	}

	/**
	 * 验证节点名称是否唯一 通过行政区代码和是否为节点代码验证节点名称
	 * 
	 * @param code
	 * @return
	 */
	@RequestMapping("/check_node_name")
	@ResponseBody
	public String checkNodeName(
			@RequestParam("newNodeName") String newNodeName,
			@RequestParam("orgCode") String orgCode) {
		try {
			String checkStr = orgCode + "1";
			if (nodeService.checkNodeName(newNodeName, checkStr)) {
				return FORM_CHECK_FAIL;
			} else {
				return FORM_CHECK_SUCCESS;
			}
		} catch (ServiceException e) {
			return FORM_CHECK_FAIL;
		}
	}

	/**
	 * 获取二级行政区
	 */
	@RequestMapping(value = "/get_city", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> getCity(Model model, String prov) {
		try {
			return jsonSuccessDataResult("获取二级行政区",
					orgInfoService.getCity(prov));
		} catch (Exception e) {
			return jsonFailResult("获取二级行政区失败");
		}
	}

	/**
	 * 获取三级行政区
	 */
	@RequestMapping(value = "/get_town", method = RequestMethod.GET)
	@ResponseBody
	public Map<String, Object> getTown(Model model, String city) {
		try {
			return jsonSuccessDataResult(" 获取三级行政区",
					orgInfoService.getTown(city));
		} catch (Exception e) {
			return jsonFailResult(" 获取三级行政区失败");
		}
	}

	/**
	 * 节点查询
	 * 
	 * @param request
	 * @param model
	 * @param selectedNode
	 * @return
	 */
	@RequestMapping(value = "/node_info_display", method = RequestMethod.GET)
	public String nodeInfoDisplay(Model model, String dataType) {
		return "registry/node_info_display";
	}

	/**
	 * 节点详情
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/node_info_detail")
	public String nodeInfoDetail(HttpServletRequest request, Model model,
			String selectedNodeId) {
		try {
			model.addAttribute("nodeInfo", nodeService.get(selectedNodeId));
			/*model.addAttribute("sysInfoList",
					sysInfoService.getSysInfoByNodeId(selectedNodeId));*/
			return "registry/node_info_detail";
		} catch (Exception e) {
			return toAlertPage(model, "获取节点详情失败");
		}
	}

	@RequestMapping(value = "/node_info_send_request")
	public String nodeInfoSendRequest(Model model) {
		return "exch/send_exch_rel_request";
	}

	/**
	 * 节点管理，节点树
	 * 
	 * @param model
	 * @param pager
	 * @param searchCode
	 * @param searchName
	 * @return
	 */
	@RequestMapping(value = "/node_info_mgr", method = RequestMethod.GET)
	@TurboMenu(belongToMenu = LEAF_MENU.NODE_MGR)
	public String nodeMgr(Model model) {
		try {
			RegistResult registResult = registryPermissionMgr.isManagerNode();
			String ismgr = registResult.getResult().getStatus();
			if(NodeInfoParam.isManaagerNode() && NodeInfoParam.isMwr()){
				ismgr = "1";
			}
			
			model.addAttribute("localNode", nodeService.getLocalNode());
			model.addAttribute("treeData",nodeService.getRootNodeTree(false, true));
			model.addAttribute("ismgr", ismgr);
			model.addAttribute("permission",registryPermissionMgr.getNodePermission(regionCode));
		} catch (Exception e) {
			logger.error("获取节点信息失败", e);
			return toAlertPage(model, e.getMessage());
		}
		return "registry/node_info_mgr";
	}

	@RequestMapping(value = "/node_info_tree")
	public void nodeTree(Model model, String id, HttpServletResponse response) {
		try {
			writeString(response, nodeService.nodeTree(id));
		} catch (Exception e) {
			logger.error("获取节点树失败", e);
		}
	}

	/**
	 * 验证用户名唯一性
	 * 
	 * @param newValue
	 * @param oldValue
	 * @return
	 */
	@RequestMapping("/is_nodename_unique")
	@ResponseBody
	public String isNodeNameUnique(
			@RequestParam("newNodeName") String newValue,
			@RequestParam("oldValue") String oldValue) {
		try {
			NodeInfo node = nodeService.getLocalNode();
			if(node == null){
				return FORM_CHECK_SUCCESS;
			}
			if (nodeService.isPropertyUnique("node_name", newValue.trim(),
					oldValue.trim(), node.getNodeCode().substring(0, 6))) {
				return FORM_CHECK_SUCCESS;
			} else {
				return FORM_CHECK_FAIL;
			}
		} catch (Exception e) {
			return FORM_CHECK_FAIL;
		}
	}

	@RequestMapping("/check_installUrl")
	@ResponseBody
	public String checkInstallUrl(@RequestParam("installUrl") String installUrl) {
			if(HttpUtil.checkUrl(installUrl))	 {
				return FORM_CHECK_SUCCESS;
	        } else{
	        	return FORM_CHECK_FAIL;
	        }
	}
	/**
	 * 节点更新验证节点访问地址
	 * @param installUrl
	 * @param nodeCode
	 * @return
	 */
	@RequestMapping("/check_installurl_update")
	@ResponseBody
	public String checkInstallUrlUpdate(@RequestParam("installUrl") String installUrl,@RequestParam("oldValue") String nodeCode) {
		try {	
			if(HttpUtil.checkUrl(installUrl))	 {
				String code= distributedNodeInfoService.getNodeCode(installUrl);
				if("".equals(code) || !nodeCode.equals(code)){
					return FORM_CHECK_FAIL;
				}
				return FORM_CHECK_SUCCESS;
	        } else{
	        	return FORM_CHECK_FAIL;
	        }
		} catch (ServiceException e) {
			logger.error("发址验证失败", e);
			return FORM_CHECK_FAIL;
		}
	}
	@RequestMapping(value = "/node_info_init", method = RequestMethod.GET)
	public String nodeInit(Model model,HttpSession httpSession) {
		try {
			String orgCode = NodeInfoParam.NODE_REGION_CODE;
			NodeInfo localNode = nodeService.getLocalNode();
			if(localNode != null){
				if(localNode.getNodeCode().indexOf(orgCode+ NodeInfoParam.NODE_NET_TYPE) != -1){
					httpSession.setAttribute(LOCAL_NODE_SESSION_KEY, localNode);
					return "redirect:/monitor/ontime.do";
				}else{
					model.addAttribute("msg", "行政区编码与数据库已注册的本节点信息不匹配，请检查交换平台配置文件，修改后请重启交换平台服务！");
				}
			}else{
				if(NodeInfoParam.isManaagerNode() && NodeInfoParam.isMwr()){
					int maxCode=nodeService.getMaxNodeCode(orgCode+ NodeInfoParam.NODE_NET_TYPE);
					DecimalFormat df = new DecimalFormat("00");  
					String nodeCode = orgCode+ NodeInfoParam.NODE_NET_TYPE+df.format(maxCode); 
					model.addAttribute("pid", NodeInfoParam.MWR_NODE_PID);
					model.addAttribute("nodeCode", nodeCode);
					model.addAttribute("orgInfo",orgInfoService.get(orgCode));
					model.addAttribute("netType",NodeInfoParam.NODE_NET_TYPE);
					model.addAttribute("hasGap",NodeInfoParam.hasGap);
					model.addAttribute("installUrl",NodeInfoParam.LOCAL_IP );
					model.addAttribute("adminEmail",NodeInfoParam.ADMIN_EMAIL);
				}else{
					String pNodeName = "";
					String pNodeCode =orgInfoService.getParentCode(orgCode);
					OrgInfo pOrgNode = orgInfoService.get(pNodeCode);
					OrgInfo localOrgNode = orgInfoService.get(orgCode);
					if(pOrgNode == null ){
						model.addAttribute("msg", "行政区编码错误，请检查交换平台配置文件，修改后请重启交换平台服务！");
					}else{
						pNodeName = pOrgNode.getAdNm();
						String localNodeName = localOrgNode.getAdNm();
						model.addAttribute("msg", "请联系上级管理节点 【"+AppTagEl.ctname("NET_TYPE", NodeInfoParam.NODE_NET_TYPE)+"】【行政区："+pNodeName+"】管理员，对本节点【行政区："+localNodeName+"】进行注册！");
					}
				}
			}
		} catch (Exception e) {
			logger.error("注册节点信息失败", e);
			return toAlertPage(model, e.getMessage());
		}
		return "registry/node_info_init";
	}
	
	@RequestMapping(value = "/init_node_info", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> InitNode(Model model,HttpSession httpSession,  NodeInfo vo, String newNodeName) {
		try {
			vo.setId(UUIDGenerator.getUUID());
			vo.setNodeName(newNodeName);
			vo.setPid(NodeInfoParam.MWR_NODE_PID);
			vo.setHasGap(NodeInfoParam.hasGap);
			vo.setNetType(NodeInfoParam.NODE_NET_TYPE);
			vo.setStatus("1");
			vo.setIsLocal("1");
			vo.setIsMgrNode("1");
			vo.setMtime(new Date());
			
			//初始化时候判断是否有网闸
			if (NodeInfoParam.hasGap.equals("1")){//有网闸的时候就初始化使用本节点网闸
				List<GapOwnerConf> list=gapOwnerConfService.getAllByUser(vo.getNodeCode());
				if (list!=null && !list.isEmpty()) {
					for (GapOwnerConf gapOwnerConf : list) {
						gapOwnerConfService.delete(gapOwnerConf);
					}
				}
				GapOwnerConf conf=new GapOwnerConf();
				conf.setId(UUIDGenerator.getUUID());//
				conf.setGapOwner(vo.getNodeCode());//网闸所有者节点编码
				conf.setGapUser(vo.getNodeCode());//网闸用户节点编码
				conf.setStatus("1");//未删除
				conf.setMtime(new Date());
				gapOwnerConfService.insertOrUpdate(conf);
				
				//初始化默认的网闸
				GapUserConf userConf=new GapUserConf();
				userConf.setId(UUIDGenerator.getUUID());
				userConf.setGapOwner(vo.getNodeCode());
				userConf.setMtime(new Date());
				gapUserConfService.insert(userConf);
			}
			
			nodeService.insert(vo);
			LocalConfCallBack.onLocalNodeInit(vo);
			httpSession.setAttribute(LOCAL_NODE_SESSION_KEY, vo);
			return jsonSuccessResult("节点初始化成功");
		} catch (ServiceException e) {
			return jsonFailResult("节点初始化失败");
		}catch (NiceException e) {
			return jsonFailResult("节点初始化失败");
		}
	}
	/**
	 * 编码唯一性
	 * @param newValue
	 * @param oldValue
	 * @return
	 */
	@RequestMapping("/is_nodecode_unique")
	@ResponseBody
	public String isNodeCodeUnique(
			@RequestParam("nodeCode") String newValue,
			@RequestParam("oldValue") String oldValue) {
		try {
			if (newValue.equals(oldValue)) {
				return FORM_CHECK_SUCCESS;
			}
			NodeInfo node = nodeService.getNodeByNodeCode(newValue);
			if (node == null) {
				return FORM_CHECK_SUCCESS;
			} else {
				return FORM_CHECK_FAIL;
			}
		} catch (Exception e) {
			return FORM_CHECK_FAIL;
		}
	}
}
